﻿#include "ScreenshotWindow.h"
#include "FlowLayout.h"
#include "ShareItemView.h"
#include <QDebug>

ScreenshotWindow::ScreenshotWindow(QWidget* parent)
    : QWidget(parent)
    , _videoProgram(new VideoProgram())
    , _captureHelper(new DibCaptureHelper())
    , _captorDirect(new VideoDXGICaptor())
{
    ui.setupUi(this);

    // 截图器
    _captorDirect->Init();
    _videoProgram->contextForWindId((HWND)ui.content->winId())->setRenderType(RenderType::fit);

    _timer = new QTimer(this);
    connect(_timer, SIGNAL(timeout()), this, SLOT(onTimer()));

    // 成员列表小窗口控件
    FlowLayout* flowLayout = new FlowLayout(15, 17, 17);
    ui.content->setLayout(flowLayout);
}

ScreenshotWindow::~ScreenshotWindow()
{
    on_end_clicked();
    _timer->deleteLater();

    if (_captureHelper)
    {
        delete _captureHelper;
        _captureHelper = nullptr;
    }

    if (_captorDirect)
    {
        delete _captorDirect;
        _captorDirect = nullptr;
    }

    if (_videoProgram)
    {
        delete _videoProgram;
        _videoProgram = nullptr;
    }
}

void ScreenshotWindow::closeEvent(QCloseEvent* e)
{
    this->deleteLater();
}

void ScreenshotWindow::onTimer()
{
#ifndef true
    if (!_captureHelper || !_captureHelper->Capture() || !_captureHelper->GetBitmapAddress())
    {
        return;
    }

    const RECT& rect = _captureHelper->GetClientRect();
    unsigned char* bits = (unsigned char*)malloc(_captureHelper->GetBitmapDataSize() + 1024 *100);
    memcpy(bits, _captureHelper->GetBitmapAddress(), _captureHelper->GetBitmapDataSize());

    VideoBuffer* buffer = new VideoBuffer();

    buffer->width = rect.right - rect.left;
    buffer->height = rect.bottom - rect.top;
    buffer->buffer = std::shared_ptr<unsigned char>(bits);
    buffer->type = ImageType::RGB;

    std::shared_ptr<VideoBuffer> videoBuffer(buffer);
    _videoProgram->draw(videoBuffer, (HWND)ui.content->winId());

#else
    if (!_captorDirect)
    {
        return;
    }

    RECT rect = _captorDirect->GetClientRect();

    int width = rect.right - rect.left;
    int height = rect.bottom - rect.top;

    unsigned char* bits = (unsigned char*)malloc(width * height * 4);

    if (!_captorDirect->CaptureImage(bits))
    {
        free(bits);
        return;
    }

    VideoBuffer* buffer = new VideoBuffer();

    buffer->width = width;
    buffer->height = height;
    buffer->buffer = std::shared_ptr<unsigned char>(bits);
    buffer->type = ImageType::RGBA;

    std::shared_ptr<VideoBuffer> videoBuffer(buffer);
    _videoProgram->draw(videoBuffer, (HWND)ui.content->winId());
#endif
}

void ScreenshotWindow::on_list_clicked()
{
    on_end_clicked();

    foreach(ShareItemView * item, ui.content->findChildren<ShareItemView*>())
    {
        delete item;
    }

    std::vector<Capturer> capturers;
    DibCaptureHelper::EnumCapturers(&capturers);

    QLayout* flowLayout = ui.content->layout();

    for (Capturer& data : capturers)
    {
        ShareItemView* member = new ShareItemView(this);
        flowLayout->addWidget(member);

        member->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
        member->setMinimumSize(220, 168);
        member->setMaximumSize(220, 168);
        member->setData(data);

        // 绑定信号
        connect(member, &ShareItemView::clicked, this, &ScreenshotWindow::itemClicked);
    }
}

// 窗口缩略图点击
void ScreenshotWindow::itemClicked(ShareItemView* inItem)
{
    foreach(ShareItemView * item, ui.content->findChildren<ShareItemView*>())
    {
        if (item == inItem)
        {
            item->setSelected(true);
        }
        else
        {
            item->setSelected(false);
        }
    }
}

void ScreenshotWindow::on_start_clicked()
{
    Capturer* data = nullptr;

    foreach(ShareItemView * item, ui.content->findChildren<ShareItemView*>())
    {
        if (item->selected())
        {
            data = &item->data();
            break;
        }
    }

    if (!data)
    {
        return;
    }

    // 根据找到的窗口句柄显示窗口
    ShowWindow((HWND)data->hwnd, SW_SHOWNORMAL);
    SetForegroundWindow((HWND)data->hwnd);
    _captureHelper->ChangeWindowHandle(*data);

    foreach(ShareItemView* item, ui.content->findChildren<ShareItemView*>())
    {
        delete item;
    }

    _timer->start(16);
    ui.content->setUpdatesEnabled(false);
}

void ScreenshotWindow::on_end_clicked()
{
    _timer->stop();
    ui.content->setUpdatesEnabled(true);
    ui.content->update();
}
